最后更新时间:2020年12月4日
离线地图显示方法
离线地图数据类型包括离线矢量地图和离线瓦片地图,两种地图加载显示的方式也略有不同:
加载地图有多种方法,不同的方法适用于不同的数据类型,具有不同的应用场景。离线矢量地图、离线瓦片地图显示的核心方法如下表所示,从表中可以观察到,它们具有三种相同的方法,另外各自具有一种独有的方法,开发者可根据数据类型、实际需求来确定采用哪种方法。
方法 | 接口 | 地图类型 | 使用场景 |
---|---|---|---|
加载地图文档 | loadFromFile / loadFromFileAsync | 矢量 / 瓦片 | 最常用,适于地图文档中只有一个地图的情况,若有多个地图则默认加载第一个。 |
加载地图文档对应索引的地图 | loadFromDocument / loadFromDocumentAsync | 矢量 / 瓦片 | 适于加载有多个地图的地图文档,可控制加载某个地图。 |
通过地图文档获取Map | setMap / setMapAsync | 矢量 / 瓦片 | 适于加载地图之前需处理的情况,如删除部分图层、获取信息等。 |
通过数据库创建图层,从而构建Map | setMap / setMapAsync | 矢量 | 源数据为离线矢量数据(.hdb数据库,兼容.mgdb数据库),没有组织地图文档“.mapx”时,只能采用此方法。 |
基于ServerLayer实例化Map | setMap / setMapAsync | 瓦片 | 直接使用代码加载瓦片地图(.mut瓦片),不用在桌面工具中配置地图文档。 |
加载离线矢量地图
一般有如下四种方式:
一、加载离线矢量地图文档: loadFromDocument / loadFromDocumentAsync
调用loadFromDocument / loadFromDocumentAsync方法加载地图文档,此方法是加载离线地图最常用、最简单的一种。前提是必须事先组织配置好mapx地图文档文件。
//引用类库(无需开发人员手动编写) //import com.zondy.mapgis.android.mapview.MapView; 10.3版本 import com.zondy.mapgis.map.view.mapview.MapView; //import com.zondy.mapgis.android.environment.Environment.AuthorizeCallback; 10.3版本 import com.zondy.mapgis.environment.Environment.AuthorizeCallback; //定义MapView对象 private MapView mMapView; //获取移动端设备sd卡的根目录 public final static String rootPath = Environment.getExternalStorageDirectory().getPath(); public final static String systemPath = Environment.getExternalStorageDirectory().getPath() + "/MapGISSample/"; //环境初始化,必须在使用SDK各组件之前调用,会自动建立根目录结构 com.zondy.mapgis.environment.Environment.initialize(systemPath, this); //授权请求 com.zondy.mapgis.environment.Environment.requestAuthorization(this, new AuthorizeCallback() { @Override //授权完成后回调 public void onComplete() { //获取MapView对象 mMapView = (MapView) findViewById(R.id.mapView); //同步方法 mMapView.loadFromFile(MainActivity.rootPath + "/MapGISSample/Map/MapShow/WuHan/WuHan.mapx"); //异步方法 mMapView.loadFromFileAsync(MainActivity.rootPath + "/MapGISSample/Map/MapShow/WuHan/WuHan.mapx"); //异步加载地图回调监听 mMapView.setMapLoadListener(new MapView.MapViewMapLoadListener() { @Override public void mapViewWillStartLoadingMap(MapView arg0, String arg1) { //开始加载地图 } @Override public void mapViewDidFinishLoadingMap(MapView arg0, String arg1) { //地图加载完成 } @Override public void mapViewDidFailLoadingMap(MapView arg0, String arg1) { //地图加载失败 } }); } });
代码说明:如果采用异步方法加载地图,可以为地图视图设置地图加载回调监听器,监听地图的加载情况。
二、加载离线矢量地图文档对应索引的地图:loadFromDocument / loadFromDocumentAsync
通过loadFromDocument / loadFromDocumentAsync来加载地图文档对应索引的地图,可以加载mapx地图文档中的指定地图,同样适用于离线矢量地图、离线瓦片地图。
//创建文档对象 Document mapDoc = new Document(); //打开地图文档 mapDoc.open(MainActivity.rootPath+"/MapGISSample/Map/MapShow/WuHan/WuHan.mapx"); //同步方法:在地图视图中加载第1个地图 mMapView.loadFromDocument(mapDoc, 0); //异步方法:利用地图加载完成的回调方法判断地图加载是否成功 mMapView.loadFromDocumentAsync(mapDoc, 0, new MapViewFinishCallback() { @Override public void onDidFinish(boolean arg0) { if (arg0) { //地图加载完成 } else { //地图加载失败 } } });
三、通过地图文档获取Map:setMap / setMapAsync
通过地图文档Document获取Map,调用setMap / setMapAsync方法加载地图。同样可以加载地图文档中指定的地图。
//创建文档对象 Document mapDoc = new Document(); //打开地图文档 mapDoc.open(MainActivity.rootPath+"/MapGISSample/Map/MapShow/WuHan/WuHan.mapx"); //通过地图文档获取地图对象 map = mapDoc.getMaps().getMap(0); //同步方法:通过地图视图对象设置地图 mMapView.setMap(map); //异步方法:可监听地图的加载情况 mMapView.setMapAsync(map, new MapViewFinishCallback() { @Override public void onDidFinish(boolean arg0) { if (arg0) { //地图加载完成 } else { //地图加载失败 } } });
代码说明:利用setMap或setMapAsync将地图Map赋予给地图视图MapView时,Map对象需定义为成员变量,从而实现生命周期的正确管理。
四、通过数据库创建图层,从而构建Map:setMap / setMapAsync
通过数据库DataBase获取数据,创建图层,从而构建Map,然后调用setMap / setMapAsync方法加载地图。此方法只适用于离线矢量数据(.hdb数据库,兼容.mgdb数据库)。
String offlineDataBasePath = MainActivity.rootPath+ "/MapGISSample/Map/MapShow/WuHan/WuHan.hdb"; Map map = new Map(); String strGDBName = ""; int offPath = offlineDataBasePath.lastIndexOf("."); int offName = offlineDataBasePath.lastIndexOf("/"); strGDBName = offlineDataBasePath.substring(offName, offPath); //构造数据库对象 //DataBase dataBase = new DataBase(); Server svr = new Server(); if(svr.connect("MapGISLocalPlus", "", "") > 0) { //连接数据库 boolean bAttach = svr.attachGDB(strGDBName, offlineDataBasePath, null); if(bAttach) { //打开数据库 DataBase dataBase = svr.openGDB(strGDBName); // DataBase dataBase = DataBase.openByURLNew(offlineDataBasePath); //dataBase.open(offlineDataBasePath); if (dataBase.hasOpened()) { //简单要素类 // IntList list1 = dataBase.getXclseIDs(XClsType.SFCls, 0); int[] list1 = dataBase.getXclses(XClsType.XSFCls, 0); for (int i = 0; i < list1.length; i++) { //创建VectorLayer图层对象,设置URL和Name SFeatureCls sfCls = new SFeatureCls(dataBase); if(sfCls.open(list1[i], 0) > 0) { VectorLayer vectorLayer = new VectorLayer(VectorLayerType.SFclsLayer); if(vectorLayer.attachData(sfCls)) { //添加图层 map.append(vectorLayer); } } } //注记类 int[] list2 = dataBase.getXclses(XClsType.XACls, 0); for (int i = 0; i < list2.length; i++) { //创建VectorLayer图层对象,设置URL和Name AnnotationCls annCls = new AnnotationCls(dataBase); if(annCls.open(list1[i], 0) > 0) { VectorLayer vectorLayer = new VectorLayer(VectorLayerType.AnnLayer); if(vectorLayer.attachData(annCls)) { //添加图层 map.append(vectorLayer); annCls.close(); } } } //同步加载地图 mapView.setMap(map); //异步方法 // mapView.setMapAsync(map, new MapViewFinishCallback() { // @Override // public void onDidFinish(boolean arg0) { // if (arg0) { // Toast.makeText(ShowDocVectorMap_Activity.this, "地图加载完成\n说明:地图显示的效果依mapx决定,从数据库中读取数据只能显示属于最原始的效果", Toast.LENGTH_SHORT).show(); // } else { // Toast.makeText(ShowDocVectorMap_Activity.this, "地图加载失败", Toast.LENGTH_SHORT).show(); // } // } // }); } } }
加载离线瓦片地图
加载离线瓦片地图有如下方式:
一、参考离线矢量地图文档前3种方式
可以参考离线矢量地图文档前3种方式加载显示离线瓦片地图,前提是必须事先组织配置好瓦片地图的mapx地图文档文件。
1、加载离线瓦片地图文档: loadFromDocument / loadFromDocumentAsync
2、加载离线瓦片地图文档对应索引的瓦片地图:loadFromDocument / loadFromDocumentAsync
3、通过离线瓦片地图文档获取Map:setMap / setMapAsync
二、【推荐】通过ImageLayer的方法创建服务图层,从而构建Map:setMap / setMapAsync
通过ImageLayer类创建服务图层,调用服务图层的setURL()方法设置离线瓦片地图文件路径,然后通过Map类的append()方法加入到地图中,最后调用MapView类的setMap/setMapAsync方法将地图加载到地图容器中显示。
String offlineDataBasePath = MainActivity.rootPath+ "/MapGISSample/Map/MapShow/WorldMKTTile.mut"; //创建服务图层 ImageLayer serverLayer = new ImageLayer(); //创建地图服务 MapServer mapserver = ImageLayer.createMapServer(MapServer.MAPSERVER_TYPE_TDF); //为地图服务设置URL:mut瓦片文件路径 mapserver.setURL(offlineTileFilePath); //为服务图层设置地图服务 serverLayer.setMapServer(mapserver); map = new Map(); map.append(serverLayer); //同步方法 mapView.setMap(map); //异步方法 // mapView.setMapAsync(map, new MapView.MapViewFinishCallback() { // @Override // public void onDidFinish(boolean arg0) { // if (arg0) { // Toast.makeText(ShowDocTileMap_Activity.this, "瓦片地图加载成功", Toast.LENGTH_SHORT).show(); // } else { // Toast.makeText(ShowDocTileMap_Activity.this, "瓦片地图加载失败", Toast.LENGTH_SHORT).show(); // } // } // });
加载离线栅格数据
加载离线栅格数据有如下方式:
一、通过地图文档方式加载
此方式需将栅格数据图层先组织为地图文档,将地图文档与数据库hdb文件一起拷贝到移动端设备。
//地图文档路径 String strMapxPath = MainActivity.rootPath + "/MapGISSample/Map/MapShow/RasterDataset/RaseterDataset1.mapx"; //加载离线栅格数据地图文档 mapView.loadFromFile(strMapxPath); //加载地图的监听 mapView.setMapLoadListener(new MapView.MapViewMapLoadListener() { @Override public void mapViewWillStartLoadingMap(MapView mapView, String s) { Toast.makeText(ShowDocRasterDataset_Activity.this, "开始加载地图", Toast.LENGTH_SHORT).show(); } @Override public void mapViewDidFinishLoadingMap(MapView mapView, String s) { Toast.makeText(ShowDocRasterDataset_Activity.this, "地图加载完成", Toast.LENGTH_SHORT).show(); } @Override public void mapViewDidFailLoadingMap(MapView mapView, String s) { Toast.makeText(ShowDocRasterDataset_Activity.this, "地图加载失败", Toast.LENGTH_SHORT).show(); } });
二、通过图层方式加载
此方式直接读取hdb数据库上的栅格图层数据或者离线本地栅格文件进行显示,需要先将数据库hdb文件或栅格数据文件一起拷贝到移动端设备。
//数据库文件路径 String dbFilePath = MainActivity.rootPath + "/MapGISSample/Map/MapShow/RasterDataset/rasterdataset.hdb"; //附加数据库 AttachDatabase(dbFilePath); int pos = dbFilePath.lastIndexOf('/'); if (pos < 0) return; String dbName = dbFilePath.substring(pos+1); pos = dbName.lastIndexOf('.'); if (pos > 0) dbName = dbName.substring(0, pos); String dirPath = dbFilePath.substring(0, dbFilePath.lastIndexOf('/')); //数据源 Server svr = new Server(); if (svr.connect("MapGISLocalPlus", "", "") < 1) return; //打开数据库 DataBase db = svr.openGDB(dbName); if (db == null) { svr.disConnect(); return; } String dbUrl = db.getURL(); int[] rsIDs = db.getXclses(XClsType.XRds, 0 ); if (rsIDs == null || rsIDs.length < 1){ db.close(); svr.disConnect(); return; } ArrayListstrList = new ArrayList (); for (int id:rsIDs) { String rsName = db.getXclsName(XClsType.XRds, id); strList.add(rsName); break; } db.close(); svr.disConnect(); if (strList.size() < 1) return; //hdb数据库中的栅格图层 m_map = new Map(); RasterLayer layer = new RasterLayer(); String layerUrl = dbUrl+ "/ras/" + strList.get(0); boolean bFlag = layer.setURL(layerUrl); if (layer.connectData()){ m_map.append(layer); } //栅格数据tif文件 RasterLayer layer2 = new RasterLayer(); layer2.setURL("file://@"+ dirPath + "/gaocheng.tif"); if (layer2.connectData()){ m_map.append(layer2); } //通过地图视图对象设置地图 mapView.setMap(m_map); mapView.restore(true); //加载地图的监听 mapView.setMapLoadListener(new MapView.MapViewMapLoadListener() { @Override public void mapViewWillStartLoadingMap(MapView mapView, String s) { Toast.makeText(ShowDocRasterDataset_Activity.this, "开始加载地图", Toast.LENGTH_SHORT).show(); } @Override public void mapViewDidFinishLoadingMap(MapView mapView, String s) { Toast.makeText(ShowDocRasterDataset_Activity.this, "地图加载完成", Toast.LENGTH_SHORT).show(); } @Override public void mapViewDidFailLoadingMap(MapView mapView, String s) { Toast.makeText(ShowDocRasterDataset_Activity.this, "地图加载失败", Toast.LENGTH_SHORT).show(); } });
private boolean AttachDatabase(String dbFilePath) { int pos = dbFilePath.lastIndexOf('/'); if (pos < 0) return false; String dbName = dbFilePath.substring(pos+1); pos = dbName.lastIndexOf('.'); if (pos > 0) dbName = dbName.substring(0, pos); //数据源 Server svr = new Server(); File file = new File(dbFilePath); if (!file.exists()) return false; if (svr.connect("MapGISLocalPlus", "", "") < 1) return false; int[] dbIDs = svr.getGdbs(); if (dbIDs != null && dbIDs.length > 0){ for (int a:dbIDs ) { svr.detachGDB(a); } } //附加数据库 long rtn = svr.attachDB(dbName, dbFilePath, ""); svr.disConnect(); return false; }
显示效果如下所示: